package com.fucheng.client;

import com.fucheng.common.RpcRequest;
import com.fucheng.common.RpcResponse;
import com.fucheng.registry.ServiceDiscovery;
import com.fucheng.registry.ZookeeperServiceDiscovery;
import com.fucheng.server.ServiceConfig;
import com.fucheng.transport.NettyRpcClient;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
import java.util.List;

/**
 * 客户端动态代理类：拦截接口调用并通过 Netty 发送请求
 */
public class RpcClientProxy {

    private final ServiceDiscovery discovery;

    public RpcClientProxy() {
        this.discovery = new ZookeeperServiceDiscovery(); // 可切换为其他注册中心
    }

    // 生成接口的代理对象
    @SuppressWarnings("unchecked")
    public <T> T getProxy(ServiceConfig<T> config) {
        return (T) Proxy.newProxyInstance(
                config.getInterfaceClass().getClassLoader(),
                new Class<?>[]{config.getInterfaceClass()},
                new RemoteInvocationHandler(config)
        );
    }

    // 动态调用处理器
    private class RemoteInvocationHandler implements InvocationHandler {


        private final ServiceConfig<?> serviceConfig;

        public RemoteInvocationHandler(ServiceConfig<?> serviceConfig) {

            this.serviceConfig = serviceConfig;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 构造请求对象
            RpcRequest request = new RpcRequest();
            request.setInterfaceName(serviceConfig.getInterfaceClass().getName());
            request.setMethodName(method.getName());
            request.setParams(args);
            request.setParamsTypes(method.getParameterTypes());
            request.setVersion(serviceConfig.getVersion());
            request.setServiceName(serviceConfig.getServiceName());

            // 服务发现
            List<String> addressList = discovery.getServices(serviceConfig.getServiceName() + ":" + serviceConfig.getVersion());
            if (addressList.isEmpty()) {
                throw new RuntimeException("无可用服务提供者：" + serviceConfig.getServiceName());
            }

            // 默认取第一个（可扩展为负载均衡）
            String[] hostPort = addressList.get(0).split(":");
            String host = hostPort[0];
            int port = Integer.parseInt(hostPort[1]);

            // Netty 发起远程调用
            NettyRpcClient client = new NettyRpcClient();
            RpcResponse response = client.send(request, host, port);

            return response.getData();
        }
    }

}
